package com.zealfi.wk.service.impl;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.ObservableExecutionMode;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import com.zealfi.wk.api.pojo.User;
import com.zealfi.wk.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import rx.Observable;

import java.util.concurrent.Future;

/**
 * Created by kuan at 2018-04-13 下午 3:26
 */
@Service
public class UserServiceImpl implements UserService {
    public static final String URL = "http://USER-SERVICE/user";

    @Autowired
    private RestTemplate restTemplate;

    @Override
    @HystrixCommand
    public User getUserById(String id) {
        return restTemplate.getForObject(URL + "/{1}", User.class, id);
    }

    @Override
    @HystrixCommand
    public Future<User> getUserByIdAsync(String id) {
        return new AsyncResult<User>() {
            @Override
            public User invoke() {
                return restTemplate.getForObject(URL + "/{1}", User.class, id);
            }
        };
    }

    @Override
    @HystrixCommand(observableExecutionMode = ObservableExecutionMode.EAGER)
    public Observable<User> getHotObservableUserById(String id) {
        return getColdObservableUserById(id);
    }

    @Override
    @HystrixCommand(observableExecutionMode = ObservableExecutionMode.LAZY)
    public Observable<User> getColdObservableUserById(String id) {
        return Observable.create((observer) -> {
            try {
                if (!observer.isUnsubscribed()) {
                    User user = restTemplate.getForObject(URL + "/{1}", User.class, id);
                    observer.onNext(user);
                    observer.onCompleted();
                }
            } catch (RestClientException e) {
                observer.onError(e);
            }
        });
    }
}
